/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dao;

import dao.exceptions.IllegalOrphanException;
import dao.exceptions.NonexistentEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import ecfdb.Fellah;
import ecfdb.Facture;
import java.util.ArrayList;
import java.util.List;
import ecfdb.LegumesDepot;
import ecfdb.CreditFellah;
import ecfdb.Depot;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author QEMLAB
 */
public class DepotJpaController implements Serializable {

    public DepotJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Depot depot) {
        if (depot.getFactureList() == null) {
            depot.setFactureList(new ArrayList<Facture>());
        }
        if (depot.getLegumesDepotList() == null) {
            depot.setLegumesDepotList(new ArrayList<LegumesDepot>());
        }
        if (depot.getCreditFellahList() == null) {
            depot.setCreditFellahList(new ArrayList<CreditFellah>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Fellah idFellah = depot.getIdFellah();
            if (idFellah != null) {
                idFellah = em.getReference(idFellah.getClass(), idFellah.getIdfellah());
                depot.setIdFellah(idFellah);
            }
            List<Facture> attachedFactureList = new ArrayList<Facture>();
            for (Facture factureListFactureToAttach : depot.getFactureList()) {
                factureListFactureToAttach = em.getReference(factureListFactureToAttach.getClass(), factureListFactureToAttach.getIdfacture());
                attachedFactureList.add(factureListFactureToAttach);
            }
            depot.setFactureList(attachedFactureList);
            List<LegumesDepot> attachedLegumesDepotList = new ArrayList<LegumesDepot>();
            for (LegumesDepot legumesDepotListLegumesDepotToAttach : depot.getLegumesDepotList()) {
                legumesDepotListLegumesDepotToAttach = em.getReference(legumesDepotListLegumesDepotToAttach.getClass(), legumesDepotListLegumesDepotToAttach.getIdlegumesDepot());
                attachedLegumesDepotList.add(legumesDepotListLegumesDepotToAttach);
            }
            depot.setLegumesDepotList(attachedLegumesDepotList);
            List<CreditFellah> attachedCreditFellahList = new ArrayList<CreditFellah>();
            for (CreditFellah creditFellahListCreditFellahToAttach : depot.getCreditFellahList()) {
                creditFellahListCreditFellahToAttach = em.getReference(creditFellahListCreditFellahToAttach.getClass(), creditFellahListCreditFellahToAttach.getIdcredit());
                attachedCreditFellahList.add(creditFellahListCreditFellahToAttach);
            }
            depot.setCreditFellahList(attachedCreditFellahList);
            em.persist(depot);
            if (idFellah != null) {
                idFellah.getDepotList().add(depot);
                idFellah = em.merge(idFellah);
            }
            for (Facture factureListFacture : depot.getFactureList()) {
                Depot oldDepotOfFactureListFacture = factureListFacture.getDepot();
                factureListFacture.setDepot(depot);
                factureListFacture = em.merge(factureListFacture);
                if (oldDepotOfFactureListFacture != null) {
                    oldDepotOfFactureListFacture.getFactureList().remove(factureListFacture);
                    oldDepotOfFactureListFacture = em.merge(oldDepotOfFactureListFacture);
                }
            }
            for (LegumesDepot legumesDepotListLegumesDepot : depot.getLegumesDepotList()) {
                Depot oldDepotOfLegumesDepotListLegumesDepot = legumesDepotListLegumesDepot.getDepot();
                legumesDepotListLegumesDepot.setDepot(depot);
                legumesDepotListLegumesDepot = em.merge(legumesDepotListLegumesDepot);
                if (oldDepotOfLegumesDepotListLegumesDepot != null) {
                    oldDepotOfLegumesDepotListLegumesDepot.getLegumesDepotList().remove(legumesDepotListLegumesDepot);
                    oldDepotOfLegumesDepotListLegumesDepot = em.merge(oldDepotOfLegumesDepotListLegumesDepot);
                }
            }
            for (CreditFellah creditFellahListCreditFellah : depot.getCreditFellahList()) {
                Depot oldIdDepotOfCreditFellahListCreditFellah = creditFellahListCreditFellah.getIdDepot();
                creditFellahListCreditFellah.setIdDepot(depot);
                creditFellahListCreditFellah = em.merge(creditFellahListCreditFellah);
                if (oldIdDepotOfCreditFellahListCreditFellah != null) {
                    oldIdDepotOfCreditFellahListCreditFellah.getCreditFellahList().remove(creditFellahListCreditFellah);
                    oldIdDepotOfCreditFellahListCreditFellah = em.merge(oldIdDepotOfCreditFellahListCreditFellah);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Depot depot) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Depot persistentDepot = em.find(Depot.class, depot.getIddepot());
            Fellah idFellahOld = persistentDepot.getIdFellah();
            Fellah idFellahNew = depot.getIdFellah();
            List<Facture> factureListOld = persistentDepot.getFactureList();
            List<Facture> factureListNew = depot.getFactureList();
            List<LegumesDepot> legumesDepotListOld = persistentDepot.getLegumesDepotList();
            List<LegumesDepot> legumesDepotListNew = depot.getLegumesDepotList();
            List<CreditFellah> creditFellahListOld = persistentDepot.getCreditFellahList();
            List<CreditFellah> creditFellahListNew = depot.getCreditFellahList();
            List<String> illegalOrphanMessages = null;
            for (Facture factureListOldFacture : factureListOld) {
                if (!factureListNew.contains(factureListOldFacture)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Facture " + factureListOldFacture + " since its depot field is not nullable.");
                }
            }
            for (LegumesDepot legumesDepotListOldLegumesDepot : legumesDepotListOld) {
                if (!legumesDepotListNew.contains(legumesDepotListOldLegumesDepot)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain LegumesDepot " + legumesDepotListOldLegumesDepot + " since its depot field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (idFellahNew != null) {
                idFellahNew = em.getReference(idFellahNew.getClass(), idFellahNew.getIdfellah());
                depot.setIdFellah(idFellahNew);
            }
            List<Facture> attachedFactureListNew = new ArrayList<Facture>();
            for (Facture factureListNewFactureToAttach : factureListNew) {
                factureListNewFactureToAttach = em.getReference(factureListNewFactureToAttach.getClass(), factureListNewFactureToAttach.getIdfacture());
                attachedFactureListNew.add(factureListNewFactureToAttach);
            }
            factureListNew = attachedFactureListNew;
            depot.setFactureList(factureListNew);
            List<LegumesDepot> attachedLegumesDepotListNew = new ArrayList<LegumesDepot>();
            for (LegumesDepot legumesDepotListNewLegumesDepotToAttach : legumesDepotListNew) {
                legumesDepotListNewLegumesDepotToAttach = em.getReference(legumesDepotListNewLegumesDepotToAttach.getClass(), legumesDepotListNewLegumesDepotToAttach.getIdlegumesDepot());
                attachedLegumesDepotListNew.add(legumesDepotListNewLegumesDepotToAttach);
            }
            legumesDepotListNew = attachedLegumesDepotListNew;
            depot.setLegumesDepotList(legumesDepotListNew);
            List<CreditFellah> attachedCreditFellahListNew = new ArrayList<CreditFellah>();
            for (CreditFellah creditFellahListNewCreditFellahToAttach : creditFellahListNew) {
                creditFellahListNewCreditFellahToAttach = em.getReference(creditFellahListNewCreditFellahToAttach.getClass(), creditFellahListNewCreditFellahToAttach.getIdcredit());
                attachedCreditFellahListNew.add(creditFellahListNewCreditFellahToAttach);
            }
            creditFellahListNew = attachedCreditFellahListNew;
            depot.setCreditFellahList(creditFellahListNew);
            depot = em.merge(depot);
            if (idFellahOld != null && !idFellahOld.equals(idFellahNew)) {
                idFellahOld.getDepotList().remove(depot);
                idFellahOld = em.merge(idFellahOld);
            }
            if (idFellahNew != null && !idFellahNew.equals(idFellahOld)) {
                idFellahNew.getDepotList().add(depot);
                idFellahNew = em.merge(idFellahNew);
            }
            for (Facture factureListNewFacture : factureListNew) {
                if (!factureListOld.contains(factureListNewFacture)) {
                    Depot oldDepotOfFactureListNewFacture = factureListNewFacture.getDepot();
                    factureListNewFacture.setDepot(depot);
                    factureListNewFacture = em.merge(factureListNewFacture);
                    if (oldDepotOfFactureListNewFacture != null && !oldDepotOfFactureListNewFacture.equals(depot)) {
                        oldDepotOfFactureListNewFacture.getFactureList().remove(factureListNewFacture);
                        oldDepotOfFactureListNewFacture = em.merge(oldDepotOfFactureListNewFacture);
                    }
                }
            }
            for (LegumesDepot legumesDepotListNewLegumesDepot : legumesDepotListNew) {
                if (!legumesDepotListOld.contains(legumesDepotListNewLegumesDepot)) {
                    Depot oldDepotOfLegumesDepotListNewLegumesDepot = legumesDepotListNewLegumesDepot.getDepot();
                    legumesDepotListNewLegumesDepot.setDepot(depot);
                    legumesDepotListNewLegumesDepot = em.merge(legumesDepotListNewLegumesDepot);
                    if (oldDepotOfLegumesDepotListNewLegumesDepot != null && !oldDepotOfLegumesDepotListNewLegumesDepot.equals(depot)) {
                        oldDepotOfLegumesDepotListNewLegumesDepot.getLegumesDepotList().remove(legumesDepotListNewLegumesDepot);
                        oldDepotOfLegumesDepotListNewLegumesDepot = em.merge(oldDepotOfLegumesDepotListNewLegumesDepot);
                    }
                }
            }
            for (CreditFellah creditFellahListOldCreditFellah : creditFellahListOld) {
                if (!creditFellahListNew.contains(creditFellahListOldCreditFellah)) {
                    creditFellahListOldCreditFellah.setIdDepot(null);
                    creditFellahListOldCreditFellah = em.merge(creditFellahListOldCreditFellah);
                }
            }
            for (CreditFellah creditFellahListNewCreditFellah : creditFellahListNew) {
                if (!creditFellahListOld.contains(creditFellahListNewCreditFellah)) {
                    Depot oldIdDepotOfCreditFellahListNewCreditFellah = creditFellahListNewCreditFellah.getIdDepot();
                    creditFellahListNewCreditFellah.setIdDepot(depot);
                    creditFellahListNewCreditFellah = em.merge(creditFellahListNewCreditFellah);
                    if (oldIdDepotOfCreditFellahListNewCreditFellah != null && !oldIdDepotOfCreditFellahListNewCreditFellah.equals(depot)) {
                        oldIdDepotOfCreditFellahListNewCreditFellah.getCreditFellahList().remove(creditFellahListNewCreditFellah);
                        oldIdDepotOfCreditFellahListNewCreditFellah = em.merge(oldIdDepotOfCreditFellahListNewCreditFellah);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = depot.getIddepot();
                if (findDepot(id) == null) {
                    throw new NonexistentEntityException("The depot with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Depot depot;
            try {
                depot = em.getReference(Depot.class, id);
                depot.getIddepot();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The depot with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Facture> factureListOrphanCheck = depot.getFactureList();
            for (Facture factureListOrphanCheckFacture : factureListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Depot (" + depot + ") cannot be destroyed since the Facture " + factureListOrphanCheckFacture + " in its factureList field has a non-nullable depot field.");
            }
            List<LegumesDepot> legumesDepotListOrphanCheck = depot.getLegumesDepotList();
            for (LegumesDepot legumesDepotListOrphanCheckLegumesDepot : legumesDepotListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Depot (" + depot + ") cannot be destroyed since the LegumesDepot " + legumesDepotListOrphanCheckLegumesDepot + " in its legumesDepotList field has a non-nullable depot field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Fellah idFellah = depot.getIdFellah();
            if (idFellah != null) {
                idFellah.getDepotList().remove(depot);
                idFellah = em.merge(idFellah);
            }
            List<CreditFellah> creditFellahList = depot.getCreditFellahList();
            for (CreditFellah creditFellahListCreditFellah : creditFellahList) {
                creditFellahListCreditFellah.setIdDepot(null);
                creditFellahListCreditFellah = em.merge(creditFellahListCreditFellah);
            }
            em.remove(depot);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Depot> findDepotEntities() {
        return findDepotEntities(true, -1, -1);
    }

    public List<Depot> findDepotEntities(int maxResults, int firstResult) {
        return findDepotEntities(false, maxResults, firstResult);
    }

    private List<Depot> findDepotEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Depot.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Depot findDepot(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Depot.class, id);
        } finally {
            em.close();
        }
    }

    public int getDepotCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Depot> rt = cq.from(Depot.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
